//===============================================================================
// Microsoft patterns & practices
// Web Service Software Factory
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Microsoft.Practices.RepositoryFactory.SchemaDiscovery.ObjectModel.Base;
using Microsoft.Practices.RepositoryFactory.SchemaDiscovery.ObjectModel.Oracle;
using System.Globalization;
#endregion

namespace Microsoft.Practices.RepositoryFactory.SchemaDiscovery.Translators.Oracle.Helpers
{
    /// <summary/>
    internal static class OracleTranslatorHelper
    {
        #region Public Implementation
        /// <summary>
        /// Gets the direction.
        /// </summary>
        /// <param name="dbValue">The db value.</param>
        /// <returns></returns>
        public static ParameterDirection GetDirection(string dbValue)
        {
            ParameterDirection direction = ParameterDirection.Input;

            switch(dbValue.ToLowerInvariant())
            {
                case "in":
                    direction = ParameterDirection.Input;
                    break;
                case "out":
                    direction = ParameterDirection.Output;
                    break;
                case "in/out": // this handles SQL Server IN/OUT parameters.
                    direction = ParameterDirection.InputOutput;
                    break;
                // TODO: Added in_out to handle Oracle IN/OUT parameters.
                case "in_out":
                    direction = ParameterDirection.InputOutput;
                    break;
                default:
                    break;
            }

            return direction;
        }

        /// <summary>
        /// Determines whether the specified db value is nullable.
        /// </summary>
        /// <param name="dbValue">The db value.</param>
        /// <returns>
        /// 	<c>true</c> if the specified db value is nullable; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsNullable(string dbValue)
        {
            return string.Compare(dbValue, "Y", StringComparison.InvariantCultureIgnoreCase) == 0;
        }

        /// <summary>
        /// Gets the precision.
        /// </summary>
        /// <param name="rowValue">The row value.</param>
        /// <returns></returns>
        public static Byte GetPrecision(object rowValue)
        {
            Byte response;

            if(!Byte.TryParse(rowValue.ToString(), out response))
            {
                response = 0;
            }

            return response;
        }

        /// <summary>
        /// Gets the scale.
        /// </summary>
        /// <param name="rowValue">The row value.</param>
        /// <returns></returns>
        public static Int16 GetScale(object rowValue)
        {
            Int16 response;

            if(!Int16.TryParse(rowValue.ToString(), out response))
            {
                response = 0;
            }

            return response;
        }

        /// <summary>
        /// Gets the size.
        /// </summary>
        /// <param name="rowValue">The row value.</param>
        /// <returns></returns>
        public static int GetSize(object rowValue)
        {
            int response;

            if(!Int32.TryParse(rowValue.ToString(), out response))
            {
                response = 0;
            }

            return response;
        }

        /// <summary>
        /// Gets the size of the parameter.
        /// </summary>
        /// <remarks>
        /// Size is used for parameters of the following types: 
        /// OracleDbType.Blob 
        /// OracleDbType.Char
        /// OracleDbType.Clob
        /// OracleDbType.LongRaw 
        /// OracleDbType.NChar 
        /// OracleDbType.NClob
        /// OracleDbType.NVarchar2 
        /// OracleDbType.Raw
        /// OracleDbType.Varchar2 
        /// </remarks>
        /// <param name="providerType">Type of the provider.</param>
        /// <param name="parameter">The parameter.</param>
        /// <returns>Procedure parameter size.</returns>
        public static int GetParameterSize(DatabaseType providerType, DataRow parameter)
        {
           // providerType no longer used - can be refactored out later
           string lengthSemantics = parameter["CHAR_USED"].ToString();
           if (lengthSemantics == "C" || lengthSemantics == "0")
           {
              //uses CHAR length semantics (C)
              return GetSize(parameter["DATA_PRECISION"].ToString());
           }
           else if (lengthSemantics == "B")
           {
              //uses BYTE length semantics (B)
              return GetSize(parameter["DATA_LENGTH"].ToString());
           }
           else
           {
              return 0;
           }
        }

        /// <summary>
        /// Gets the default parameter value.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static object GetDefaultParameterValue(Type type)
        {
            if(((type == typeof(short)) || (type == typeof(int))) || ((type == typeof(long)) || (type == typeof(byte))))
            {
                return 0;
            }
            if(type == typeof(string))
            {
                return string.Empty;
            }
            if(type == typeof(bool))
            {
                return true;
            }
            if(((type == typeof(decimal)) || (type == typeof(float))) || (type == typeof(double)))
            {
                return 0;
            }
            if(type == typeof(DateTime))
            {
                return DateTime.Today;
            }
            string text1 = type.Name;
            return DBNull.Value;
        }

        /// <summary>
        /// Gets the name of the qualified.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public static string GetQualifiedName(string name)
        {
            return ('[' + name + ']');
        }

        /// <summary>
        /// Gets the name of the object.
        /// </summary>
        /// <param name="dbSchema">The db schema.</param>
        /// <param name="dbObject">The db object.</param>
        /// <returns></returns>
        public static string GetObjectName(string dbSchema, string dbObject)
        {
            return string.Format(CultureInfo.CurrentCulture, Properties.Resources.EscapeObjectName, dbObject);
        }

        #endregion
    }
}
